home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / Small Eiffel 0.4.8 / lib_std / collection.e < prev    next >
Encoding:
Text File  |  1997-04-13  |  9.7 KB  |  461 lines  |  [TEXT/ttxt]

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. deferred class COLLECTION[E]
  5. -- 
  6. -- Common abstract definition of a sequentiable collection of 
  7. -- objects. Such a collection is traversable using a simple 
  8. -- INTEGER index from `lower' to `upper'. Items can be added,
  9. -- changed or removed.
  10. -- 
  11. -- The SmallEiffel standard library (lib_std) provides four
  12. -- implementations : ARRAY[E], FIXED_ARRAY[E], LINK_LIST[E] 
  13. -- and LINK2_list[E]. All implementations have exactly the 
  14. -- same behavior. Switching from one implementation to another 
  15. -- only change the memory used and the execution time.
  16. --
  17.  
  18. inherit
  19.    ANY
  20.       undefine copy, is_equal
  21.       redefine fill_tagged_out_memory
  22.       end;
  23.  
  24. feature -- Indexing :
  25.  
  26.    lower: INTEGER is
  27.      -- Lower index bound.
  28.       deferred
  29.       end;
  30.  
  31.    upper: INTEGER is
  32.      -- Upper index bound.
  33.       deferred
  34.       end;
  35.  
  36.    frozen valid_index(index: INTEGER): BOOLEAN is
  37.      -- True when `index' is valid (ie. inside actual 
  38.      -- bounds of the collection).
  39.       do
  40.      Result := lower <= index and then index <= upper;
  41.       ensure      
  42.      Result = (lower <= index and index <= upper);
  43.       end;
  44.  
  45. feature -- Counting :
  46.  
  47.    count: INTEGER is
  48.      -- Number of elements actually stored in the collection.
  49.       deferred
  50.       ensure
  51.      Result = upper - lower + 1
  52.       end;
  53.  
  54.    empty: BOOLEAN is
  55.      -- Is collection empty?
  56.       do
  57.      Result := (count = 0);
  58.       end;
  59.  
  60. feature -- Accessing :
  61.  
  62.    item, infix "@" (index: INTEGER): E is
  63.      -- Item at position `index'.
  64.       require
  65.      valid_index(index)
  66.       deferred
  67.       end;
  68.  
  69.    first: like item is
  70.       require
  71.      count >= 1
  72.       do
  73.      Result := item(lower);
  74.       end;
  75.    
  76.    last: like item is
  77.       require
  78.      count >= 1
  79.       do
  80.      Result := item(upper);
  81.       end;
  82.  
  83. feature -- Writing :
  84.  
  85.    put(element: like item; index: INTEGER) is
  86.      -- Put `element' at position `index'.
  87.       require
  88.      valid_index(index)
  89.       deferred
  90.       ensure
  91.      item(index) = element;
  92.      count = old count
  93.       end;
  94.  
  95.    swap(i1, i2: INTEGER) is
  96.       require
  97.      valid_index(i1);
  98.      valid_index(i2)
  99.       local
  100.      tmp: like item;
  101.       do
  102.      tmp := item(i1);
  103.      put(item(i2),i1);
  104.      put(tmp,i2);
  105.       ensure
  106.      item(i1) = old item(i2);
  107.      item(i2) = old item(i1);
  108.      count = old count
  109.       end;
  110.         
  111.    set_all_with(v: like item) is
  112.      -- Set all item with value `v'.
  113.       deferred
  114.       ensure
  115.      count = old count
  116.       end;
  117.    
  118.    set_slice_with(v: like item; lower_index, upper_index: INTEGER) is
  119.      -- Set all item with `v'.
  120.       require
  121.      lower_index <= upper_index;
  122.      valid_index(lower_index);
  123.      valid_index(upper_index)
  124.       local
  125.      i: INTEGER;
  126.       do
  127.      from  
  128.         i := lower_index;
  129.      until
  130.         i > upper_index
  131.      loop
  132.         put(v,i);
  133.         i := i + 1;
  134.      end;      
  135.       ensure
  136.      count = old count
  137.       end;
  138.    
  139.    clear_all is
  140.      -- Set all items to default values.
  141.       local
  142.      value: like item;
  143.       do
  144.      set_all_with(value);
  145.       ensure
  146.      count = old count;
  147.      all_cleared
  148.       end;
  149.    
  150. feature -- Adding :
  151.  
  152.    add_first(element: like item) is
  153.       deferred
  154.       ensure
  155.      first = element;
  156.      count = 1 + old count;
  157.      lower = old lower;
  158.      upper = 1 + old upper
  159.       end;
  160.  
  161.    add_last(element: like item) is
  162.       deferred
  163.       ensure
  164.      last = element;
  165.      count = 1 + old count;
  166.      lower = old lower;
  167.      upper = 1 + old upper
  168.       end;
  169.  
  170.    add(element: like item; index: INTEGER) is
  171.      -- Add `element' at rank `index'.
  172.      -- Range [`index' .. `upper'] is translated by 1 to 
  173.      -- the right and then, `element' is written at `index'.
  174.       require
  175.      lower <= index;
  176.          index <= upper + 1
  177.       deferred
  178.       ensure
  179.      item(index) = element;
  180.          count = 1 + old count;
  181.      upper = 1 + old upper
  182.       end;
  183.  
  184. feature -- Modification :
  185.  
  186.    force(element: E; index: INTEGER) is
  187.      -- Put `element' at position `index'. Collection is
  188.      -- resized if `index' is not inside current bounds.
  189.      -- New bounds are initialized with default values.
  190.       require
  191.      index >= lower
  192.       deferred
  193.       ensure
  194.      valid_index(index); 
  195.      item(index) = element
  196.       end;
  197.  
  198.    from_collection(model: COLLECTION[like item]) is
  199.       -- Initialize the current object with the contents of `model'.
  200.       require
  201.      model /= Void
  202.       deferred
  203.       ensure
  204.      count = model.count;
  205.       end;
  206.  
  207. feature -- Removing :
  208.  
  209.    remove_first is
  210.      -- Remove the first element of the collection.
  211.      -- Indexing 
  212.       require
  213.      not empty
  214.       deferred
  215.       ensure
  216.      count = (old count) - 1;
  217.          (lower = (old lower) + 1) xor (upper = (old upper) - 1) 
  218.       end;
  219.  
  220.    remove(index: INTEGER) is
  221.      -- Remove one element at position `index'. Followings 
  222.      -- elements (after `index') are moved one position left.
  223.       require
  224.      valid_index(index)
  225.       deferred
  226.       ensure
  227.      count = (old count) - 1;
  228.      upper = (old upper) - 1;
  229.       end;
  230.  
  231.    remove_last is
  232.       require
  233.      not empty;
  234.       deferred
  235.       ensure
  236.      count = (old count) - 1;
  237.      upper = (old upper) - 1
  238.       end;
  239.  
  240.    clear is
  241.      -- Discard all items.
  242.       deferred
  243.       ensure
  244.      empty;
  245.       end;
  246.  
  247. feature -- Looking and Searching :
  248.  
  249.    has(x: like item): BOOLEAN is
  250.      -- Look for `x' using `equal' for comparison.
  251.       do
  252.      if count > 0 then
  253.         Result := index_of(x) <= upper;
  254.      end;
  255.       end;
  256.    
  257.    fast_has(x: like item): BOOLEAN is
  258.      -- Same as `has' but use `=' for comparison.
  259.       do
  260.      if count > 0 then
  261.         Result := fast_index_of(x) <= upper;
  262.      end;
  263.       end;
  264.    
  265.    index_of(element: like item): INTEGER is
  266.      -- Give the index of the first occurrence of `element' using
  267.      -- `is_equal' for comparison.
  268.      -- Answer `upper + 1' when `element' is not inside.
  269.       deferred
  270.       ensure
  271.      lower <= Result;
  272.      Result <= upper + 1;
  273.      Result <= upper implies equal(element,item(Result));
  274.       end;
  275.    
  276.    fast_index_of(element: like item): INTEGER is
  277.      -- Same as `index_of' but use `=' for comparison.
  278.       deferred
  279.       ensure
  280.      lower <= Result;
  281.      Result <= upper + 1;
  282.      Result <= upper implies element = item(Result);
  283.       end;
  284.    
  285. feature -- Looking and comparison :
  286.  
  287.    all_cleared: BOOLEAN is
  288.      -- Are all items set to default values?
  289.       deferred
  290.       end;
  291.  
  292.    nb_occurrences(element: like item): INTEGER is
  293.      -- Number of occurrences using `equal'.
  294.      -- See also `fast_nb_occurrences' to chose
  295.      -- the apropriate one.
  296.       deferred
  297.       ensure
  298.      Result >= 0
  299.       end;
  300.       
  301.    fast_nb_occurrences(element: like item): INTEGER is
  302.      -- Number of occurrences using `='.
  303.       deferred
  304.       ensure
  305.      Result >= 0;
  306.       end;
  307.       
  308. feature -- Printing :
  309.  
  310.    fill_tagged_out_memory is
  311.       local
  312.      i: INTEGER;
  313.      v: like item;
  314.       do
  315.      tagged_out_memory.append("lower: "); 
  316.      lower.append_in(tagged_out_memory);
  317.      tagged_out_memory.append(" upper: "); 
  318.      upper.append_in(tagged_out_memory);
  319.      tagged_out_memory.append(" [");
  320.      from  
  321.         i := lower;
  322.      until
  323.         i > upper or else tagged_out_memory.count > 2048
  324.      loop
  325.         v := item(i);
  326.         if v = Void then
  327.            tagged_out_memory.append("Void");
  328.         else
  329.            v.out_in_tagged_out_memory;
  330.         end;
  331.         if i < upper then
  332.            tagged_out_memory.extend(' ');
  333.         end;
  334.         i := i + 1;
  335.      end;
  336.      if i <= upper then
  337.         tagged_out_memory.append(" ..."); 
  338.      end;
  339.      tagged_out_memory.extend(']'); 
  340.       end;
  341.  
  342. feature -- Other Features :
  343.  
  344.    replace_all(x, r: like item) is
  345.       local
  346.      i: INTEGER;
  347.       do
  348.      from
  349.         i := lower;
  350.      until 
  351.         i > upper
  352.      loop
  353.         if equal_like(item(i),x) then
  354.            put(r,i);
  355.         end;
  356.         i := i + 1;
  357.      end;
  358.       end;
  359.    
  360.    fast_replace_all(x, r: like item) is
  361.       local
  362.      i: INTEGER;
  363.       do
  364.      from 
  365.         i := lower;
  366.      until
  367.         i > upper
  368.      loop
  369.         if item(i) = x then
  370.            put(r, i);
  371.         end;
  372.         i := i + 1;
  373.      end;
  374.       end;
  375.  
  376.    move(lower_index, upper_index, distance: INTEGER) is
  377.      -- Move range `lower_index' .. `upper_index' by `distance' 
  378.      -- positions. Negative distance moves towards lower indices.
  379.      -- Free places get default values.
  380.       require
  381.      lower_index <= upper_index;
  382.      valid_index(lower_index);
  383.      valid_index(lower_index + distance);
  384.      valid_index(upper_index);
  385.      valid_index(upper_index + distance)
  386.       local
  387.      default_value: like item;
  388.      i: INTEGER;
  389.       do
  390.      if distance = 0 then
  391.      elseif distance < 0 then
  392.         from  
  393.            i := lower_index;
  394.         until
  395.            i > upper_index
  396.         loop
  397.            put(item(i),i + distance);
  398.            put(default_value,i);
  399.            i := i + 1;
  400.         end;
  401.      else
  402.         from  
  403.            i := upper_index;
  404.         until
  405.            i < lower_index
  406.         loop
  407.            put(item(i),i + distance);
  408.            put(default_value,i);
  409.            i := i - 1;
  410.         end;
  411.      end;
  412.       ensure
  413.      count = old count
  414.       end;
  415.  
  416.    slice(low, up: INTEGER): like Current is
  417.      -- Create a new collection initialized with elements of
  418.      -- range `low'..`up'. Result has the same dynamic type 
  419.      -- as Current collection. The `lower' index of the new 
  420.      -- collection is the same as `lower' of Current.
  421.       require
  422.      valid_index(low);
  423.      valid_index(up);
  424.      low <= up
  425.       deferred
  426.       ensure
  427.      same_type(Result);
  428.      Result.count = up - low + 1;
  429.      Result.lower = lower
  430.       end;
  431.  
  432. feature -- The Guru section :
  433.  
  434.    free is
  435.      -- Free the memory used by the Current COLLECTION (objects
  436.      -- pointed by the Current COLLECTION are not affected). 
  437.      -- Assume you don't use Current any more. 
  438.       deferred
  439.       end;
  440.    
  441. feature {NONE}
  442.  
  443.    frozen equal_like(e1, e2: like item): BOOLEAN is
  444.      -- Note: this feature is called to avoid calling `equal'
  445.      -- on expanded types (no automatic conversion to 
  446.      -- corresponding reference type).
  447.       do
  448.      if e1.is_basic_expanded_type then
  449.         Result := e1 = e2;
  450.      elseif e1.is_expanded_type then
  451.         Result := e1.is_equal(e2);
  452.      elseif e1 = e2 then
  453.         Result := true;
  454.      elseif e1 = Void or else e2 = Void then
  455.      else
  456.         Result := e1.is_equal(e2);
  457.      end;
  458.       end;
  459.  
  460. end -- COLLECTION[E}
  461.